﻿Imports System.Linq
Imports System.Collections.Generic
Imports SISSAT.BusinessLayer.Managers
Imports SISSAT.BusinessLayer.Services
Imports SISSAT.BusinessLayer.DataViews
Imports SISSAT.BusinessLayer.DomainModels

Namespace Views
    Public Class GradePointAverageControlPresenter

        Private Property View As IGradePointAverageControlView
        Private Property ExaminationService As IExaminationService
        Private Property ScheduleService As IScheduleService
        Private Property MatriculationService As IMatriculationService

        Public Sub New(view As IGradePointAverageControlView)
            ExaminationService = New ExaminationService
            ScheduleService = New ScheduleService
            MatriculationService = New MatriculationService

            Me.View = view
            AddHandler Me.View.OnInitialization, AddressOf OnInitialization
            AddHandler Me.View.OnSelectedIndexChange, AddressOf OnSelectedIndexChange
        End Sub

        Private Sub OnInitialization(isReadOnly As Boolean)
            If isReadOnly Then
                Return
            End If

            Dim matriculations As IEnumerable(Of Matriculation) = MatriculationService.ReadAllByEmployeeId(Me.View.StudentId)
            Dim entities As IEnumerable(Of Schedule) = From entity In matriculations
                                                       Let schedule As Schedule = ScheduleService.ReadById(entity.ScheduleId)
                                                       Select schedule

            Dim dataSource As IEnumerable(Of KeyValuePair(Of String, String)) = _
                From entity In entities
                Let syKey As String = String.Format("{0}|{1}", entity.SchoolYear, entity.Semester)
                Let syValue As String = String.Format("SY {0}/{1} Semester", entity.SchoolYear, entity.Semester)
                Order By entity.SchoolYear Descending, entity.Semester Descending
                Select New KeyValuePair(Of String, String)(syKey, syValue)

            Me.View.DropDownListDataSource = dataSource.Distinct()
        End Sub

        Private Sub OnSelectedIndexChange()
            Me.View.GradePointAverage = 0D
            Me.View.TotalUnits = 0D

            If String.IsNullOrEmpty(Me.View.SelectedValue) Then
                Return
            End If

            Dim delimiter() As Char = {CType("|", Char)}
            Dim selectedValue As String() = Me.View.SelectedValue.Split(delimiter)
            Dim schoolYear As String = selectedValue(0)
            Dim semester As Semesters = CType([Enum].Parse(GetType(Semesters), selectedValue(1), True), Semesters)

            Dim entities As IEnumerable(Of Matriculation) = MatriculationService.ReadAllByEmployeeId(Me.View.StudentId)
            Dim dataSource As IEnumerable(Of GradePointAverageDataView) = _
                From item In entities
                Let entity = ScheduleService.ReadById(item.ScheduleId)
                Let gradePoint = item.GradePoint
                Let majorExams As IEnumerable(Of Examination) = ExaminationService.ReadAllFilteredByMajorExams(Me.View.StudentCode, item.ScheduleId)
                Let preliminary As Decimal = (From prelim In majorExams Where prelim.ExaminationType.ExaminationTypeId = 9 Select prelim.Grade).FirstOrDefault()
                Let midterm As Decimal = (From mt In majorExams Where mt.ExaminationType.ExaminationTypeId = 10 Select mt.Grade).FirstOrDefault()
                Let prefinals As Decimal = (From pf In majorExams Where pf.ExaminationType.ExaminationTypeId = 11 Select pf.Grade).FirstOrDefault()
                Let finals As Decimal = (From f In majorExams Where f.ExaminationType.ExaminationTypeId = 12 Select f.Grade).FirstOrDefault()
                Where entity.SchoolYear = schoolYear AndAlso entity.Semester = semester
                Select New GradePointAverageDataView With {
                    .Finals = Convert.ToString(finals),
                    .GradePoint = Convert.ToString(gradePoint),
                    .Midterms = Convert.ToString(midterm),
                    .Prefinals = Convert.ToString(prefinals),
                    .Preliminary = Convert.ToString(preliminary),
                    .ScheduleId = entity.ScheduleId,
                    .SubjectCode = entity.Subject.Code,
                    .SubjectName = entity.Subject.Name,
                    .Units = entity.Subject.Units
                }

            Me.View.RepeaterDataSource = dataSource

            Me.View.TotalUnits = (From entity In entities
                                  Let schedule = ScheduleService.ReadById(entity.ScheduleId)
                                  Where schedule.SchoolYear = schoolYear AndAlso schedule.Semester = semester AndAlso
                                        entity.GradePoint < 5D AndAlso entity.GradePoint > 0D
                                  Select schedule.Subject.Units).Sum()

            Dim gradePointAverage As Decimal = (From entity In entities
                                                Let schedule = ScheduleService.ReadById(entity.ScheduleId)
                                                Let units As Decimal = schedule.Subject.Units
                                                Where schedule.SchoolYear = schoolYear AndAlso schedule.Semester = semester
                                                Select entity.GradePoint * units).Sum()

            If (gradePointAverage > 0D AndAlso Me.View.TotalUnits > 0D) Then
                Me.View.GradePointAverage = gradePointAverage / Me.View.TotalUnits
            End If
        End Sub

    End Class
End Namespace

